home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.cs.arizona.edu
/
ftp.cs.arizona.edu.tar
/
ftp.cs.arizona.edu
/
icon
/
newsgrp
/
group00b.txt
/
000043_icon-group-sender _Tue Aug 22 07:39:52 2000.msg
< prev
next >
Wrap
Internet Message Format
|
2001-01-03
|
8KB
Return-Path: <icon-group-sender>
Received: (from root@localhost)
by baskerville.CS.Arizona.EDU (8.9.1a/8.9.1) id HAA13214
for icon-group-addresses; Tue, 22 Aug 2000 07:39:32 -0700 (MST)
Message-Id: <200008221439.HAA13214@baskerville.CS.Arizona.EDU>
Delivered-To: fixup-icon-group@CS.arizona.edu@fixme
Date: Mon, 21 Aug 2000 20:12:46 -0600
From: Cheyenne Wills <cheyenne_wills@uswest.net>
X-Accept-Language: en
To: icon-group@optima.CS.Arizona.EDU
Subject: Re: [Icon][WinNT] external C functions.
Errors-To: icon-group-errors@optima.CS.Arizona.EDU
Status: RO
Content-Length: 6815
This is a multi-part message in MIME format.
--------------30657AAB585C0267D4C3A50B
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Well.. here is some code that I hacked a long time ago to implement
dynamically loaded functions for OS/2. You might be able to hack at it
to work under WinNT. Basically your code was loaded into a DLL and the
Icon runtime could call out to it..
Anyway... enjoy...
---[fload.r]---
--------------30657AAB585C0267D4C3A50B
Content-Type: text/plain; charset=us-ascii;
name="fload.r"
Content-Disposition: inline;
filename="fload.r"
Content-Transfer-Encoding: 7bit
/*
* File: fload.r
* Contents: loadfunc.
*
* This file contains loadfunc(), the dynamic loading function for
* Unix systems having the <dlfcn.h> interface.
*
* from Icon:
* p := loadfunc(filename, funcname)
* p(arg1, arg2, ...)
*
* in C:
* int func(int argc, dptr argv)
* return -1 for failure, 0 for success, >0 for error
* argc is number of true args not including argv[0]
* argv[0] is for return value; others are true args
*/
#ifdef LoadFunc
#ifndef RTLD_LAZY /* normally from <dlfcn.h> */
#define RTLD_LAZY 1
#endif /* RTLD_LAZY */
#ifdef FreeBSD
/* Sorry, no dlerror() on FreeBSD. Fake it. */
char *dlerror(void)
{
int no;
if (0 == dlctl(NULL, DL_GETERRNO, &no))
return(strerror(no));
else
return(NULL);
}
#endif /* __FreeBSD__ */
#if COMPILER
int glue Params(( int argc, dptr dargv, dptr rslt, continuation succ_count));
#else
int glue Params(( int argc, dptr dargv) );
#endif /* COMPILER */
#if OS2
int makefunc Params((dptr d, char *name, void *funcptr));
#else
int makefunc Params((dptr d, char *name, int (*func)() ));
#endif /* OS2 */
"loadfunc(filename,funcname) - load C function dynamically."
function{0,1} loadfunc(filename,funcname)
if !cnv:C_string(filename) then
runerr(103, filename)
if !cnv:C_string(funcname) then
runerr(103, funcname)
abstract {
return proc
}
body
{
#if OS2
unsigned long modhandle;
int rc;
#passthru int (* _System funcaddr)(int argc, dptr dargv);
rc = _loadmod(filename,&modhandle);
if (rc) {
runerr(216);
}
rc = DosQueryProcAddr( modhandle, 0, funcname, &funcaddr );
if (rc) {
_freemod(modhandle);
runerr(216);
}
if (!makefunc(&result, funcname, (void *)funcaddr ) ) {
_freemod(modhandle);
runerr(305);
}
return result;
}
#else /* OS2 */
int (*func)();
static char *curfile;
static void *handle;
char errbuf[1000];
/*
* Get a library handle, reusing it over successive calls.
*/
if (!handle || !curfile || strcmp(filename, curfile) != 0) {
if (curfile)
free((pointer)curfile); /* free the old file name */
curfile = salloc(filename); /* save the new name */
handle = dlopen(filename, RTLD_LAZY); /* get the handle */
}
/*
* Load the function. Diagnose both library and function errors here.
*/
if (handle)
func = (int (*)())dlsym(handle, funcname);
if (!handle || !func) {
fprintf(stderr, "\nloadfunc(\"%s\",\"%s\"): %s\n",
filename, funcname, dlerror());
runerr(216);
}
/*
* Build and return a proc descriptor.
*/
if (!makefunc(&result, funcname, func))
runerr(305);
return result;
}
#endif /* OS2 */
end
/*
* makefunc(d, name, func) -- make function descriptor in d.
*
* Returns 0 if memory could not be allocated.
*/
int makefunc(d, name, func)
dptr d;
char *name;
#if OS2
void *func;
#else
int (*func)();
#endif /* OS2 */
{
struct b_proc *blk;
blk = (struct b_proc *)malloc(sizeof(struct b_proc));
if (!blk)
return 0;
blk->title = T_Proc;
blk->blksize = sizeof(struct b_proc);
#if COMPILER
blk->ccode = glue; /* set code addr to glue routine */
#else /* COMPILER */
blk->entryp.ccode = glue; /* set code addr to glue routine */
#endif /* COMPILER */
blk->nparam = -1; /* varargs flag */
blk->ndynam = -1; /* treat as built-in function */
blk->nstatic = 0;
blk->fstatic = 0;
blk->pname.dword = strlen(name);
blk->pname.vword.sptr = salloc(name);
blk->lnames[0].dword = 0;
blk->lnames[0].vword.sptr = (char *)func;
/* save func addr in lnames[0] vword */
d->dword = D_Proc; /* build proc descriptor */
d->vword.bptr = (union block *)blk;
return 1;
}
/*
* This glue routine is called when a loaded function is invoked.
* It digs the actual C code address out of the proc block, and calls that.
*/
#if COMPILER
int glue(argc, dargv, rslt, succ_cont)
int argc;
dptr dargv;
dptr rslt;
continuation succ_cont;
{
int i, status, (*func)();
struct b_proc *blk;
struct descrip r;
tended struct descrip p;
dargv--; /* reset pointer to proc entry */
for (i = 0; i <= argc; i++)
deref(&dargv[i], &dargv[i]); /* dereference args including proc */
blk = (struct b_proc *)dargv[0].vword.bptr; /* proc block address */
func = (int (*)())blk->lnames[0].vword.sptr; /* entry point address */
p = dargv[0]; /* save proc for traceback */
dargv[0] = nulldesc; /* set default return value */
status = (*func)(argc, dargv); /* call func */
if (status == 0) {
*rslt = dargv[0];
Return; /* success */
}
if (status < 0)
Fail; /* failure */
r = dargv[0]; /* save result value */
dargv[0] = p; /* restore proc for traceback */
if (is:null(r))
RunErr(status, NULL); /* error, no value */
RunErr(status, &r); /* error, with value */
}
#else /* COMPILER */
int glue(argc, dargv)
int argc;
dptr dargv;
{
int status;
#if OS2
#passthru int (* _System func)(int argc, dptr dargv);
void *funcptr;
#else
int (*func)();
#endif /* OS2 */
struct b_proc *blk;
struct descrip r;
tended struct descrip p;
blk = (struct b_proc *)dargv[0].vword.bptr; /* proc block address */
#if OS2
funcptr = (void *)blk->lnames[0].vword.sptr; /* entry point address */
func = funcptr;
#else
func = (int (*)())blk->lnames[0].vword.sptr; /* entry point address */
#endif
p = dargv[0]; /* save proc for traceback */
dargv[0] = nulldesc; /* set default return value */
status = (*func)(argc, dargv); /* call func */
if (status == 0)
Return; /* success */
if (status < 0)
Fail; /* failure */
r = dargv[0]; /* save result value */
dargv[0] = p; /* restore proc for traceback */
if (is:null(r))
RunErr(status, NULL); /* error, no value */
RunErr(status, &r); /* error, with value */
}
#endif /* COMPILER */
#else /* LoadFunc */
static char junk; /* avoid empty module */
#endif /* LoadFunc */
--------------30657AAB585C0267D4C3A50B--